package com.hexinfo.dmpro.monitor.service.serviceparam;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.crypto.Mac;
import javax.crypto.spec.SecretKeySpec;
import java.net.URLEncoder;
import java.util.List;
import java.util.Map;


@Service
@Slf4j
public class DingDingAlarmService {

    private static final Logger logger = LoggerFactory.getLogger(DingDingAlarmService.class);

    // 应用凭证
    @Value("${warn.webhook}")
    private String webhook;   //把webhook设置成对应群的即可
    @Value("${warn.robotKey}")
    private String robotKey;

    /**
     * 钉钉群聊告警
     * @param content 消息内容
     * @param mobileList 通知具体人的手机号码列表
     * @param isAtAll 是否通知所有人
     */
    public String dingDingAlarm(String content, List<String> mobileList ,String isAtAll) {
        String timestamp = String.valueOf(System.currentTimeMillis());
        String sign = dingHmacSHA256(timestamp, robotKey);
        String webhookUrl = webhook + "&timestamp=" + timestamp + "&sign=" + sign;
        if ("1".equals(isAtAll)){
            return sendMsgToGroupChat(webhookUrl,true,mobileList,content);
        }else {
            return sendMsgToGroupChat(webhookUrl,false,mobileList,content);
        }
    }

    /**
     * 通知消息发送到群聊
     * @param webhook 钉钉机器人地址(配置机器人的webhook)
     * @param isAtAll 是否通知所有人
     * @param mobileList 通知具体人的手机号码列表
     * @param content 消息内容
     */
    public String sendMsgToGroupChat(String webhook, boolean isAtAll, List<String> mobileList, String content){
        try {
            //组装请求内容
            String reqStr = buildReqStr(content, isAtAll, mobileList);
            //推送消息(http请求)
            String result = HttpUtil.post(webhook, reqStr);
            logger.info("通知响应结果：{}",result);
            JSONObject obj = JSONObject.parseObject(result);
            logger.info("通知响应编码：{}",obj.get("errcode"));
            if (0==(int)obj.get("errcode")){
                return "1";
            }else {
                return "2";
            }
        }catch (Exception e){
            logger.error("webhook通知失败",e);
            return "2";
        }
    }

    /**
     * 组装请求报文（Map封装）
     * @param content 通知内容
     * @param isAtAll 是否@所有人
     * @param mobileList 通知具体人的手机号码
     * @return
     */
    private String buildReqStr(String content, boolean isAtAll, List mobileList) {

        //消息内容
        Map<String, String> contentMap = Maps.newHashMap();
        contentMap.put("content", content);
        //通知人
        Map atMap = Maps.newHashMap();
        //1.是否通知所有人
        atMap.put("isAtAll", isAtAll);
        //2.通知具体人的手机号码列表
        atMap.put("atMobiles", mobileList);
        //3.通知具体人的userid
        //atMap.put("atUserIds", atUserIds);

        Map reqMap = Maps.newHashMap();
        reqMap.put("msgtype", "text");
        reqMap.put("text", contentMap);
        reqMap.put("at", atMap);

        return JSON.toJSONString(reqMap);

    }

    /**
     * 钉钉自定义机器人安全设置
     * 把timestamp+"\n"+密钥当做签名字符串，使用HmacSHA256算法计算签名，然后进行Base64 encode，最后再把签名参数再进行urlEncode，得到最终的签名（需要使用UTF-8字符集）
     * @param secret
     * @return
     */
    public String dingHmacSHA256(String timestamp, String secret) {
        try {
            String stringToSign = timestamp + "\n" + secret;
            Mac mac = Mac.getInstance("HmacSHA256");
            mac.init(new SecretKeySpec(secret.getBytes("UTF-8"), "HmacSHA256"));
            byte[] signData = mac.doFinal(stringToSign.getBytes("UTF-8"));
            String sign = URLEncoder.encode(new String(Base64.encodeBase64(signData)), "UTF-8");
            return sign;
        } catch (Exception e) {
            logger.error("dingHmacSHA256加密失败", e);
        }
        return null;
    }

    /**
     * 获取通知消息
     * @return
     */
    private String getContent() {
        //钉钉机器人消息内容
        String content;
        //通过转码网站http://tool.chinaz.com/Tools/unicode.aspx
        // 选择中文转Unicode把钉钉表情转换成unicode编码，也可以直接用表情对应的中文设置
        String milkyTea = "钉钉告警[奶茶][流鼻血][流鼻血]";
        String NEWLINE = "\n";
        StringBuffer sb = new StringBuffer();
        sb.append("集群告警：")
                .append(NEWLINE)
                .append(milkyTea);
        content = sb.toString();
        return content;
    }
}